<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>

                    <h4>使用list和tuple</h4>
                    <div class="x-wiki-info"><span>4917次阅读</span></div>
                    <hr style="border-top-color:#ccc" />
                    <div class="x-wiki-content x-content"><h3 id="list">list</h3>
<p>Python内置的一种数据类型是列表：list。list是一种有序的集合，可以随时添加和删除其中的元素。</p>
<p>比如，列出班里所有同学的名字，就可以用一个list表示：</p>
<pre><code>&gt;&gt;&gt; classmates = [&#39;Michael&#39;, &#39;Bob&#39;, &#39;Tracy&#39;]
&gt;&gt;&gt; classmates
[&#39;Michael&#39;, &#39;Bob&#39;, &#39;Tracy&#39;]
</code></pre><p>变量<code>classmates</code>就是一个list。用<code>len()</code>函数可以获得list元素的个数：</p>
<pre><code>&gt;&gt;&gt; len(classmates)
3
</code></pre><p>用索引来访问list中每一个位置的元素，记得索引是从<code>0</code>开始的：</p>
<pre><code>&gt;&gt;&gt; classmates[0]
&#39;Michael&#39;
&gt;&gt;&gt; classmates[1]
&#39;Bob&#39;
&gt;&gt;&gt; classmates[2]
&#39;Tracy&#39;
&gt;&gt;&gt; classmates[3]
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
IndexError: list index out of range
</code></pre><p>当索引超出了范围时，Python会报一个IndexError错误，所以，要确保索引不要越界，记得最后一个元素的索引是<code>len(classmates) - 1</code>。</p>
<p>如果要取最后一个元素，除了计算索引位置外，还可以用<code>-1</code>做索引，直接获取最后一个元素：</p>
<pre><code>&gt;&gt;&gt; classmates[-1]
&#39;Tracy&#39;
</code></pre><p>以此类推，可以获取倒数第2个、倒数第3个：</p>
<pre><code>&gt;&gt;&gt; classmates[-2]
&#39;Bob&#39;
&gt;&gt;&gt; classmates[-3]
&#39;Michael&#39;
&gt;&gt;&gt; classmates[-4]
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
IndexError: list index out of range
</code></pre><p>当然，倒数第4个就越界了。</p>
<p>list是一个可变的有序表，所以，可以往list中追加元素到末尾：</p>
<pre><code>&gt;&gt;&gt; classmates.append(&#39;Adam&#39;)
&gt;&gt;&gt; classmates
[&#39;Michael&#39;, &#39;Bob&#39;, &#39;Tracy&#39;, &#39;Adam&#39;]
</code></pre><p>也可以把元素插入到指定的位置，比如索引号为<code>1</code>的位置：</p>
<pre><code>&gt;&gt;&gt; classmates.insert(1, &#39;Jack&#39;)
&gt;&gt;&gt; classmates
[&#39;Michael&#39;, &#39;Jack&#39;, &#39;Bob&#39;, &#39;Tracy&#39;, &#39;Adam&#39;]
</code></pre><p>要删除list末尾的元素，用<code>pop()</code>方法：</p>
<pre><code>&gt;&gt;&gt; classmates.pop()
&#39;Adam&#39;
&gt;&gt;&gt; classmates
[&#39;Michael&#39;, &#39;Jack&#39;, &#39;Bob&#39;, &#39;Tracy&#39;]
</code></pre><p>要删除指定位置的元素，用<code>pop(i)</code>方法，其中<code>i</code>是索引位置：</p>
<pre><code>&gt;&gt;&gt; classmates.pop(1)
&#39;Jack&#39;
&gt;&gt;&gt; classmates
[&#39;Michael&#39;, &#39;Bob&#39;, &#39;Tracy&#39;]
</code></pre><p>要把某个元素替换成别的元素，可以直接赋值给对应的索引位置：</p>
<pre><code>&gt;&gt;&gt; classmates[1] = &#39;Sarah&#39;
&gt;&gt;&gt; classmates
[&#39;Michael&#39;, &#39;Sarah&#39;, &#39;Tracy&#39;]
</code></pre><p>list里面的元素的数据类型也可以不同，比如：</p>
<pre><code>&gt;&gt;&gt; L = [&#39;Apple&#39;, 123, True]
</code></pre><p>list元素也可以是另一个list，比如：</p>
<pre><code>&gt;&gt;&gt; s = [&#39;python&#39;, &#39;java&#39;, [&#39;asp&#39;, &#39;php&#39;], &#39;scheme&#39;]
&gt;&gt;&gt; len(s)
4
</code></pre><p>要注意<code>s</code>只有4个元素，其中<code>s[2]</code>又是一个list，如果拆开写就更容易理解了：</p>
<pre><code>&gt;&gt;&gt; p = [&#39;asp&#39;, &#39;php&#39;]
&gt;&gt;&gt; s = [&#39;python&#39;, &#39;java&#39;, p, &#39;scheme&#39;]
</code></pre><p>要拿到<code>&#39;php&#39;</code>可以写<code>p[1]</code>或者<code>s[2][1]</code>，因此<code>s</code>可以看成是一个二维数组，类似的还有三维、四维……数组，不过很少用到。</p>
<p>如果一个list中一个元素也没有，就是一个空的list，它的长度为0：</p>
<pre><code>&gt;&gt;&gt; L = []
&gt;&gt;&gt; len(L)
0
</code></pre><h3 id="tuple">tuple</h3>
<p>另一种有序列表叫元组：tuple。tuple和list非常类似，但是tuple一旦初始化就不能修改，比如同样是列出同学的名字：</p>
<pre><code>&gt;&gt;&gt; classmates = (&#39;Michael&#39;, &#39;Bob&#39;, &#39;Tracy&#39;)
</code></pre><p>现在，classmates这个tuple不能变了，它也没有append()，insert()这样的方法。其他获取元素的方法和list是一样的，你可以正常地使用<code>classmates[0]</code>，<code>classmates[-1]</code>，但不能赋值成另外的元素。</p>
<p>不可变的tuple有什么意义？因为tuple不可变，所以代码更安全。如果可能，能用tuple代替list就尽量用tuple。</p>
<p>tuple的陷阱：当你定义一个tuple时，在定义的时候，tuple的元素就必须被确定下来，比如：</p>
<pre><code>&gt;&gt;&gt; t = (1, 2)
&gt;&gt;&gt; t
(1, 2)
</code></pre><p>如果要定义一个空的tuple，可以写成<code>()</code>：</p>
<pre><code>&gt;&gt;&gt; t = ()
&gt;&gt;&gt; t
()
</code></pre><p>但是，要定义一个只有1个元素的tuple，如果你这么定义：</p>
<pre><code>&gt;&gt;&gt; t = (1)
&gt;&gt;&gt; t
1
</code></pre><p>定义的不是tuple，是<code>1</code>这个数！这是因为括号<code>()</code>既可以表示tuple，又可以表示数学公式中的小括号，这就产生了歧义，因此，Python规定，这种情况下，按小括号进行计算，计算结果自然是<code>1</code>。</p>
<p>所以，只有1个元素的tuple定义时必须加一个逗号<code>,</code>，来消除歧义：</p>
<pre><code>&gt;&gt;&gt; t = (1,)
&gt;&gt;&gt; t
(1,)
</code></pre><p>Python在显示只有1个元素的tuple时，也会加一个逗号<code>,</code>，以免你误解成数学计算意义上的括号。</p>
<p>最后来看一个“可变的”tuple：</p>
<pre><code>&gt;&gt;&gt; t = (&#39;a&#39;, &#39;b&#39;, [&#39;A&#39;, &#39;B&#39;])
&gt;&gt;&gt; t[2][0] = &#39;X&#39;
&gt;&gt;&gt; t[2][1] = &#39;Y&#39;
&gt;&gt;&gt; t
(&#39;a&#39;, &#39;b&#39;, [&#39;X&#39;, &#39;Y&#39;])
</code></pre><p>这个tuple定义的时候有3个元素，分别是<code>&#39;a&#39;</code>，<code>&#39;b&#39;</code>和一个list。不是说tuple一旦定义后就不可变了吗？怎么后来又变了？</p>
<p>别急，我们先看看定义的时候tuple包含的3个元素：</p>
<p><img src="http://www.liaoxuefeng.com/files/attachments/001387269705541ad608276b6f7426ca59b8c2b19947243000/0" alt="tuple-0"></p>
<p>当我们把list的元素<code>&#39;A&#39;</code>和<code>&#39;B&#39;</code>修改为<code>&#39;X&#39;</code>和<code>&#39;Y&#39;</code>后，tuple变为：</p>
<p><img src="http://www.liaoxuefeng.com/files/attachments/001387269768140c7d5ca167342402989dfc75343fe900b000/0" alt="tuple-1"></p>
<p>表面上看，tuple的元素确实变了，但其实变的不是tuple的元素，而是list的元素。tuple一开始指向的list并没有改成别的list，所以，tuple所谓的“不变”是说，tuple的每个元素，指向永远不变。即指向<code>&#39;a&#39;</code>，就不能改成指向<code>&#39;b&#39;</code>，指向一个list，就不能改成指向其他对象，但指向的这个list本身是可变的！</p>
<p>理解了“指向不变”后，要创建一个内容也不变的tuple怎么做？那就必须保证tuple的每一个元素本身也不能变。</p>
<h3 id="-">小结</h3>
<p>list和tuple是Python内置的有序集合，一个可变，一个不可变。根据需要来选择使用它们。</p>
</div>

                    <hr style="border-top-color:#ccc" />

                    